// Background script to manage HLS video detection and downloads

// Store detected videos
let detectedVideos = {};

// Listen for messages from content scripts
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'hlsVideosDetected') {
    // Add detected videos to our collection
    request.videos.forEach(video => {
      // Add tabId to the video object if provided
      if (request.tabId) {
        video.tabId = request.tabId;
      }
      // Use video ID as key to avoid duplicates
      detectedVideos[video.id] = video;
    });
    
    // Log the detection
    console.log('HLS videos detected:', request.videos);
    
    // Update the extension icon badge with the number of detected videos
    updateBadgeCount();
  } else if (request.action === 'getCurrentTabId') {
    // Get the current tab ID
    chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
      if (tabs && tabs[0]) {
        sendResponse({tabId: tabs[0].id});
      } else {
        sendResponse({tabId: null});
      }
    });
    return true; // Keep the message channel open for async response
  }
  
  return true; // Keep the message channel open for async response
});

// Listen for web requests to detect HLS streams
chrome.webRequest.onBeforeRequest.addListener(
  function(details) {
    // Check if the request is for an m3u8 file or other HLS-related content
    if (details.url && (details.url.includes('.m3u8') || isHLSUrl(details.url))) {
      console.log('HLS request detected:', details.url);
      
      // Get tab information to get the page title
      chrome.tabs.get(details.tabId, (tab) => {
        // Create a video object for this HLS stream
        const video = {
          id: `hls-${Date.now()}-${details.requestId}`,
          url: details.url,
          title: tab && tab.title ? tab.title : 'HLS Stream',
          pageUrl: tab && tab.url ? tab.url : details.url,
          tabId: details.tabId
        };
        
        // Add to detected videos
        detectedVideos[video.id] = video;
        
        // Update the extension icon badge
        updateBadgeCount();
        
        console.log('HLS video added to detected videos:', video);
      });
    }
  },
  { urls: ['<all_urls>'] },
  []
);

// Helper function to check if a URL is an HLS URL
function isHLSUrl(url) {
  if (!url || typeof url !== 'string') return false;
  
  // Common patterns for HLS URLs
  const hlsPatterns = [
    /\.m3u8/,
    /hls/i,
    /stream/i,
    /playlist/i,
    /manifest/i
  ];
  
  return hlsPatterns.some(pattern => pattern.test(url));
}

// Function to update the extension icon badge with the number of detected videos
function updateBadgeCount() {
  const count = Object.keys(detectedVideos).length;
  chrome.action.setBadgeText({ text: count > 0 ? count.toString() : '' });
  chrome.action.setBadgeBackgroundColor({ color: '#4CAF50' });
}

// Listen for messages from the popup
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'getDetectedVideos') {
    // Send the current list of detected videos
    sendResponse({ videos: Object.values(detectedVideos) });
  } else if (request.action === 'downloadVideo') {
    // Handle video download request
    downloadVideo(request.videoId, request.videoTitle);
    sendResponse({ success: true });
  } else if (request.action === 'clearVideos') {
    // Clear the detected videos list
    detectedVideos = {};
    updateBadgeCount();
    sendResponse({ success: true });
  }
  
  return true; // Keep the message channel open for async response
});

// Listen for tab updates to get page titles for HLS requests
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  // When the tab is loaded, update the titles of any HLS videos from this tab
  if (changeInfo.status === 'complete' && tab.url) {
    // Find any HLS videos associated with this tab URL
    for (const [id, video] of Object.entries(detectedVideos)) {
      // If the video's page URL matches this tab's URL, update its title
      if (video.pageUrl === tab.url && tab.title) {
        detectedVideos[id].title = tab.title;
      }
      
      // Also check if the video URL is from the same domain
      try {
        const videoUrlDomain = new URL(video.url).hostname;
        const tabUrlDomain = new URL(tab.url).hostname;
        
        if (videoUrlDomain === tabUrlDomain && tab.title && video.title === 'HLS Stream') {
          detectedVideos[id].title = tab.title;
        }
      } catch (e) {
        // Ignore URL parsing errors
      }
    }
  }
});

// Function to download a video
function downloadVideo(videoId, videoTitle) {
  const video = detectedVideos[videoId];
  if (!video) {
    console.error('Video not found:', videoId);
    return;
  }
  
  // Create a more descriptive filename if we have a title
  let filename = `video-${videoId}.m3u8`;
  if (videoTitle) {
    // Clean the title for use as filename
    filename = videoTitle.replace(/[^a-zA-Z0-9\u4e00-\u9fa5\s-]/g, '').replace(/\s+/g, '-').substring(0, 50) + '.m3u8';
  } else if (video.url) {
    // Try to extract filename from URL
    try {
      const urlObj = new URL(video.url);
      const pathname = urlObj.pathname;
      const urlFilename = pathname.substring(pathname.lastIndexOf('/') + 1);
      if (urlFilename) {
        filename = urlFilename;
      }
    } catch (e) {
      // Use default filename if URL parsing fails
    }
  }
  
  // For now, we'll just download the m3u8 file directly
  // In a more advanced implementation, we would process the HLS stream
  chrome.downloads.download({
    url: video.url,
    filename: filename,
    saveAs: true
  }, (downloadId) => {
    if (chrome.runtime.lastError) {
      console.error('Download failed:', chrome.runtime.lastError);
    } else {
      console.log('Download started with ID:', downloadId);
    }
  });
}

// Clear videos when a tab is closed
chrome.tabs.onRemoved.addListener((tabId) => {
  // Remove videos associated with the closed tab
  let removedCount = 0;
  for (const [id, video] of Object.entries(detectedVideos)) {
    if (video.tabId === tabId) {
      delete detectedVideos[id];
      removedCount++;
    }
  }
  
  if (removedCount > 0) {
    updateBadgeCount();
  }
});